#ifndef MOUTH_H
#define MOUTH_H

#include <iostream>
#include "btBulletDynamicsCommon.h"
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
#include <vector>
#include "bodypart.h"
#include "src/utils/settings.h"
#include "src/utils/raycast.h"
#include "src/brainz/brainz.h"
#include "src/brainz/brainzarch.h"


using namespace std;

class Bodyowner;
class Mouth : public Bodypart
{
public:
	Mouth(btDynamicsWorld* ownerWorld, Bodyowner* owner, const btVector3& dimensions, float weight, btTransform& offset, btTransform& transform, BeColor color);
	virtual ~Mouth();

	btPairCachingGhostObject*	ghostObject;
	void				 updateGhostObjectPosition();
  btScalar     drawposition[16];
  vector<Bodypart*> touchedBodyparts;
  bool         motorEat;

  void         checkCollisions();
  void         eat();


  // Inherited from Bodypart:
  void         draw();
  void         draw(int colorsel);
  void         preprocess(vector<CritterB*>& critters, vector<Entity*>& entities, unsigned long long frameCount);
  void         process(vector<CritterB*>& critters, vector<Entity*>& entities, unsigned long long frameCount);
  void         postprocess(vector<CritterB*>& critters, vector<Entity*>& entities, unsigned long long frameCount);
  btRigidBody* validateHitBody(btCollisionObject* co, btRigidBody* b);

  // vision stuff for bobke's 'shared mass retina' openGL optimization.
  static unsigned int fb;
  static unsigned int color_tex;
  static unsigned int depth_rb;
  static unsigned int items;
  static unsigned char  *retina;
  static unsigned long long currentFrame;
  unsigned int    framePosX;
  unsigned int    framePosY;
  unsigned int    retinaColumnStart;
  unsigned int    retinaRowStart;
  unsigned int    retinaRowLength;
  unsigned int    visionPosition;
  // used for raycast_vision
  Raycast*        raycast;

  // "Great Retina" manipulation
  static void           initRetina();
  static const unsigned int*  initSetting(string settingname);
  static void           glBindVision();
  static void           glClearVision();
  static void           glUnbindVision();
  void                  renderVision(vector<CritterB*>& critters, vector<Entity*>& entities);
  void                  vision_place();
  void                  calcFramePos();
  void                  grabVision();
  void                  drawWithinSight(vector<CritterB*>& critters, vector<Entity*>&  entities);
  static unsigned int   registerInputs(BrainzArch* ba, unsigned int nextid);
  unsigned int          procInputs(Brainz& brain, unsigned int nindex);
  unsigned int          getNumberOfInputs();
  unsigned int          getNumberOfOutputs();
  static unsigned int   registerOutputs(BrainzArch* ba, unsigned int nextid);
  unsigned int          procOutputs(Brainz& brain, unsigned int nindex);
  btVector3             getScreenDirection(const int& x, const int& y);
  // Settings 
  static const unsigned int* critter_maxenergy;
  static const unsigned int* critter_sightrange;
  static const unsigned int* retinasperrow;
  static const unsigned int* critter_raycastvision;
  static const unsigned int* critter_retinasize;
  static const unsigned int* headless;

  // Object count (for vision)
  static unsigned int totalWorldMouths;
  static unsigned int currentMouthID;
  static vector<Mouth*> WorldMouths;
  unsigned int mouthID;

};
#endif
